玩 Library 當然不能錯過 p5 哇~ 先附上超豐富的 p5 example,在這裡可以挖到很多寶,要不是時間有限,很想試試看動畫+音效 p5 sound!!今天的範例也是從中找了一個,並以 react-p5 改寫,基本上 react-p5 寫法都與 p5.js 相同,只是 react-p5 幫我們包了一個 Component ,網路上找不太到 react-p5 的範例資源,但是都可以拿 p5.js 的範例來改寫很方便唷~
基本上 p5.js 有許許多多已經被封裝好的 function 讓我們可以直接使用,在繪圖和運算上都不需要自己再苦惱如何實踐,可以直接採用 p5 的功能,功能很強大舉以下這些常用類型為例:
Environment: 跟整個開發頁面相關的功能,例如取得長寬(width、height),getURLParams() 取得 url 參數等。
Color: 跟顏色相關的設定,包含 ****brightness()、color()、lightness() 等
Shape: 所有圖形繪製工具,幾何圖形、貝茲曲線、3D 繪圖等,例如用來繪製橢圓的 ellipse()
Constants: 一些常數,例如 PI,我們今天也會用到
Rendering: 渲染畫面用的函示, createCanvas() 繪製 Canvas 使用
Transform: rotate()、scale() 與圖形的變形、旋轉相關的
Data: 資料的處理以及一些寫好的 Array function
Events: 鍵盤、滑鼠等可以被監聽的事件,例如 mouseMoved()、mouseDragged()、mousePressed()
Math: 數學運算,例如 map() 在今天的範例中有使用到,定義是 take any number and scale it to a new number
Typography: 跟文字、字體相關的處理
3D: 一些讓物體看起來很 3D 的設定,包含光影、材質等
初步了解 p5 的功能後,來看看今天的練習目標 —— 做一個滿滿的重複的圖形,他們會隨著鼠標位置移動而有所變化,形成海波浪搖咧搖咧的效果。
話不多說,開始實作吧!我們今天的教學以 react-p5 為主,所以一樣先起手式:
npm install --save react-p5
接著主要的步驟可以分成
這裡很簡單,我們 import Sketch,並以 Sketch 設定 component ,因為我們用的是 typeScript 所以這裡把 p5Types 也一起 import,讓我們在設定 p5 相關函式時起以遵守 p5Types 的型別規範。
import React from 'react';
import Sketch from 'react-p5';
import p5Types from 'p5';
const PFivePage: React.FC<ComponentProps> = (props: ComponentProps) => {
const setup = () => {
}
const draw = () => {
}
return <Sketch setup={setup} draw={draw} />;
};
export default PFivePage;
接著先完成 setup function,這個 function 主要就是在繪製整個圖像空間畫布。
const setup = (p5: p5Types, canvasParentRef: Element) => {
p5.createCanvas(500, 500).parent(canvasParentRef);
p5.fill('#8D7FE9');
p5.noStroke();
};
draw function 會是整段程式碼最複雜的地方,因為要產生動畫和效果,中間一段雙層迴圈就是為了繪製出一個個的圓形,中間我們使用到 mouseX & mouseY,是為了讓動畫跟著滑鼠位置不同,而改變樣式。同時因為我們讓此動畫隨著時間重複,因此用到了 t = t + 0.01 去更新時間。
let t = 0; // time variable
const draw = (p5: p5Types) => {
p5.background(10, 10); // translucent background (creates trails)
// make a x and y grid of ellipses
for (let x = 0; x <= p5.width; x = x + 30) {
for (let y = 0; y <= p5.height; y = y + 30) {
// starting point of each circle depends on mouse position
const xAngle = p5.map(p5.mouseX, 0, 500, -4 * Math.PI, 4 * p5.PI, true);
const yAngle = p5.map(p5.mouseY, 0, 500, -4 * Math.PI, 4 * p5.PI, true);
// and also varies based on the particle's location
const angle = xAngle * (x / p5.width) + yAngle * (y / p5.height);
// each particle moves in a circle
const myX = x + 20 * p5.cos(2 * p5.PI * t + angle);
const myY = y + 20 * p5.sin(2 * p5.PI * t + angle);
p5.ellipse(myX, myY, 10); // draw particle
}
}
t = t + 0.01; // update time
};
拆解成這三個步驟後,主要的動畫就繪製完成了,是不是覺得充滿自信XD~ 有興趣的大家可以再去 p5 example clone 更多不同的動畫和互動來玩玩看唷!
程式碼參考至:https://p5js.org/examples/interaction-wavemaker.html